package repository

import (
	"boy-go/modules/generator/model"
	"boy-go/modules/generator/vo"
	"boy-go/pkg/db"
	"boy-go/pkg/request"
	"gorm.io/gorm"
	"time"
)

var (
	_selectGenTableVo = "table_id, m_table_name, m_table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark"
)

type GenTableRepository struct {
	DB *gorm.DB
}

func NewGenTableRepository() *GenTableRepository {
	return &GenTableRepository{
		DB: db.GetMasterDB(),
	}
}

func (r *GenTableRepository) GetById(tableId int64) (*model.GenTable, error) {
	db := r.DB
	m := &model.GenTable{}
	err := db.Model(&model.GenTable{}).Where("table_id = ?", tableId).First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}
func (r *GenTableRepository) GetByTableName(tableName string) (*model.GenTable, error) {
	db := r.DB
	m := &model.GenTable{}
	err := db.Model(&model.GenTable{}).Where("m_table_name = ?", tableName).First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}

func (r *GenTableRepository) List(query *vo.QueryGenTableReq, pageReq *request.PageRequest) ([]*model.GenTable, int64, error) {
	tx := r.DB.Model(&model.GenTable{})
	if query != nil {
		if query.MTableName != nil {
			tx = tx.Where("m_table_name = ?", *query.MTableName)
		}
		if query.MTableComment != nil {
			tx = tx.Where("m_table_comment = ?", *query.MTableComment)
		}
		if query.SubTableName != nil {
			tx = tx.Where("sub_table_name = ?", *query.SubTableName)
		}
		if query.SubTableFkName != nil {
			tx = tx.Where("sub_table_fk_name = ?", *query.SubTableFkName)
		}
		if query.ClassName != nil {
			tx = tx.Where("class_name = ?", *query.ClassName)
		}
		if query.TplCategory != nil {
			tx = tx.Where("tpl_category = ?", *query.TplCategory)
		}
		if query.TplWebType != nil {
			tx = tx.Where("tpl_web_type = ?", *query.TplWebType)
		}
		if query.PackageName != nil {
			tx = tx.Where("package_name = ?", *query.PackageName)
		}
		if query.ModuleName != nil {
			tx = tx.Where("module_name = ?", *query.ModuleName)
		}
		if query.BusinessName != nil {
			tx = tx.Where("business_name = ?", *query.BusinessName)
		}
		if query.FunctionName != nil {
			tx = tx.Where("function_name = ?", *query.FunctionName)
		}
		if query.FunctionAuthor != nil {
			tx = tx.Where("function_author = ?", *query.FunctionAuthor)
		}
		if query.GenType != nil {
			tx = tx.Where("gen_type = ?", *query.GenType)
		}
		if query.GenPath != nil {
			tx = tx.Where("gen_path = ?", *query.GenPath)
		}
		if query.Options != nil {
			tx = tx.Where("options = ?", *query.Options)
		}
		if query.CreateBy != nil {
			tx = tx.Where("create_by = ?", *query.CreateBy)
		}
		if query.CreateTime != nil {
			tx = tx.Where("create_time = ?", *query.CreateTime)
		}
		if query.UpdateBy != nil {
			tx = tx.Where("update_by = ?", *query.UpdateBy)
		}
		if query.UpdateTime != nil {
			tx = tx.Where("update_time = ?", *query.UpdateTime)
		}
		if query.Remark != nil {
			tx = tx.Where("remark = ?", *query.Remark)
		}
	}
	list := make([]*model.GenTable, 0)
	if pageReq != nil {
		var total int64
		if err := tx.Count(&total).Error; err != nil {
			return nil, 0, err
		}
		if total > 0 {
			tx = tx.Select(_selectGenTableVo)
			tx = db.BuildPageAndOrder(tx, &query.PageRequest, "")
			if err := tx.Find(&list).Error; err != nil {
				return nil, total, err
			}
		}
		return list, total, nil
	} else {
		tx = tx.Select(_selectGenTableVo)
		if err := tx.Find(&list).Error; err != nil {
			return nil, 0, err
		}
	}
	return list, int64(len(list)), nil
}
func (r *GenTableRepository) SelectGenTableAll() []*model.GenTable {
	//sql := "SELECT t.table_id, t.m_table_name, t.m_table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark," +
	//	" c.column_id, c.column_name, c.column_comment, c.column_type, c.struct_type, c.struct_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort" +
	//	" FROM gen_table t" +
	//	" LEFT JOIN gen_table_column c ON t.table_id = c.table_id" +
	//	" order by c.sort"
	//list := make([]*model.GenTable, 0)
	//err := r.DB.Raw(sql).Scan(&list).Error
	//if err != nil {
	//	return nil
	//}
	//return list
	db := r.DB
	list := make([]*model.GenTable, 0)
	err := db.Model(&model.GenTable{}).Order("create_time").Find(&list).Error
	if err != nil {
		return nil
	}
	return list
}

// Save 添加
func (r *GenTableRepository) Save(m *model.GenTable) error {
	currentDate := time.Now()
	m.CreateAt = &currentDate
	return r.DB.Model(&model.GenTable{}).Create(&m).Error
}

// Update 更新
func (r *GenTableRepository) Update(m *model.GenTable) error {
	currentDate := time.Now()
	m.UpdateAt = &currentDate
	return r.DB.Model(&model.GenTable{}).Where("table_id = ?", m.TableId).Omit("table_id").Updates(m).Error
}

// Delete 删除
func (r *GenTableRepository) Delete(tableId int64) error {
	return r.DB.Model(&model.GenTable{}).Where("table_id = ?", tableId).Delete(&model.GenTable{}).Error
}

// DeleteBatch 批量删除
func (r *GenTableRepository) BatchDelete(ids []string) error {
	dbErr := r.DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Model(&model.GenTable{}).Where("table_id IN ?", ids).Delete(&model.GenTable{}).Error
		if err != nil {
			return err
		}
		err = tx.Model(&model.GenTableColumn{}).Where("table_id IN ?", ids).Delete(&model.GenTableColumn{}).Error
		if err != nil {
			return err
		}
		return nil
	})
	return dbErr
}

func (r *GenTableRepository) SelectDbTableList(query *vo.QueryGenTableReq, pageReq *request.PageRequest) ([]*model.GenTable, int64, error) {
	selectSQL := "select table_name as m_table_name, table_comment as m_table_comment, create_time as create_time, update_time as update_time "
	selectCountSQL := "select count(0) "
	whereSQL := " from information_schema.tables where table_schema = (select database()) AND table_name NOT LIKE 'qrtz\\_%' AND table_name NOT LIKE 'gen\\_%' AND table_name NOT IN (select m_table_name from gen_table)"
	if query != nil {
		if query.MTableName != nil {
			whereSQL += ("AND lower(table_name) like lower(concat('%', " + *query.MTableName + ", '%'))")
		}
		if query.MTableComment != nil {
			whereSQL += ("AND lower(table_comment) like lower(concat('%', " + *query.MTableComment + ", '%'))")
		}
	}
	tx := r.DB
	list := make([]*model.GenTable, 0)
	if pageReq != nil {
		total := int64(0)
		err := tx.Raw(selectCountSQL + whereSQL).Count(&total).Error
		if err != nil {
			return nil, total, err
		}
		if total > 0 {
			offSet := 0
			limit := 10
			if pageReq.PageNum > 0 {
				offSet = (pageReq.PageNum - 1) * limit
			}
			if pageReq.PageSize > 0 {
				limit = pageReq.PageSize
			}
			sql := selectSQL + whereSQL + " order by create_time desc limit ? offset ?"
			err := tx.Raw(sql, limit, offSet).Scan(&list).Error
			return list, total, err
		}
		return nil, 0, nil
	} else {
		sql := selectSQL + whereSQL
		err := tx.Raw(sql).Find(&list).Error
		return list, int64(len(list)), err
	}
}
func (r *GenTableRepository) SelectDbTableListByNames(tables []string) ([]*model.GenTable, error) {
	sql := "select table_name as m_table_name, table_comment as m_table_comment, create_time as create_time, update_time as update_time from information_schema.tables where table_name NOT LIKE 'qrtz\\_%' and table_name NOT LIKE 'gen\\_%' and table_schema = (select database()) " +
		"and table_name in ?"
	list := make([]*model.GenTable, 0)
	err := r.DB.Raw(sql, tables).Find(&list).Error
	if err != nil {
		return nil, err
	}
	return list, nil
}
